home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / UI / MenuBar.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  23.2 KB  |  954 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        MenuBar.cpp
  3.  
  4.     Contains:    Implementation of ODMenuBar
  5.  
  6.     Owned by:    Chris Linn
  7.  
  8.     Copyright:    © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <6>      12/12/96    CSL        1607857: Added new private method
  13.                                     FindMenuAndItem, which doesn't throw.
  14.          <5>     9/24/96    eeh        1315228: Verify part wrapper passed
  15.          <4>     9/18/96    CSL        1384645: Copy doesn't work if fOtherMenus
  16.                                     is NULL.
  17.          <3>      6/7/96    eeh        1303383: check for smSystemScript in
  18.                                     SetItemString
  19.         <27>    10/23/95    RR        # 1291688 Synch with menu manager when
  20.                                     adding & removing menus, if this menu bar
  21.                                     is the current menu bar
  22.         <26>     10/8/95    TJ        Fixes Recomended by Refball
  23.         <25>     9/12/95    eeh        1283557: use SetErrorCode
  24.         <24>     8/21/95    RR         #1271358 GetMenuAndItem throws
  25.                                     kODErrInvalidCommandID. EnableCommand etc.
  26.                                     suppress this error and fail silently
  27.         <23>     8/16/95    NP        1274946: ErrorDef.idl problems. Add include
  28.                                     file.
  29.         <22>     8/15/95    RR        #1276683 remove extra new ODPrivMenuInfo.
  30.         <21>      8/3/95    RR        #1257260: Collapse B classes. Remove
  31.                                     somInit methods. Don't call IsInitialized
  32.                                     or SubclassResponsibility
  33.         <20>     7/25/95    VL        1270320: Delete foundMenu in RemoveMenu.
  34.                                     Delete elements in _fOtherMenus before
  35.                                     deleting it.
  36.         <19>     7/25/95    eeh        1259218: remove assert in SetItemString
  37.         <18>      6/8/95    RR        #1257260 Collapse base classes. #1214898
  38.                                     StdTypes.r -> ODTypes.r
  39.         <17>     5/26/95    RR        #1251403: Multithreading naming support
  40.         <16>     5/17/95    RR        #1250135/1250137/1250143 Getters increment
  41.                                     refcount
  42.         <15>     4/28/95    RR        1211085 Remove 5$ comments
  43.         <14>     4/13/95    RR        # 1216618 Added ODVolatile, #1220325
  44.                                     Removed private error code
  45.         <13>      4/7/95    RR        #1216618 Added SOM_TRY etc.
  46.         <12>      4/6/95    RR        #1211085 Remove 5$ comments
  47.         <11>      4/4/95    RR        # 1197749 Get/Set ItemString deal with
  48.                                     script code
  49.         <10>     3/22/95    RR        #1197749, 1194296 Set script code in
  50.                                     SetItemString
  51.          <9>     1/23/95    RR        # 1212896 Added EnableAll and DisableAll
  52.          <8>     1/12/95    jpa        Don't use obsolete Toolbox names [1211211]
  53.          <7>     9/29/94    RA        1189812: Mods for 68K build.
  54.          <6>     8/25/94    RR        Implemented IsValid. Added private
  55.                                     SetGeneration/GetGeneration
  56.          <5>     8/15/94    JBS        1181023:  return kODTrue in IsValid
  57.          <4>     8/15/94    CG        #1181023:  Added new IsValid API.  It is
  58.                                     not implemented yet.
  59.          <3>     7/19/94    eeh        fix to ODMenuBarCopy
  60.          <2>      7/6/94    RR        Implemented SetItemString and GetItemString
  61.          <1>     6/23/94    RR        first checked in
  62.  
  63.     To Do:
  64. */
  65.  
  66.  
  67. #define ODMenuBar_Class_Source
  68. #define VARIABLE_MACROS
  69. #include <MenuBar.xih>
  70.  
  71. #ifndef _PLFMDEF_
  72. #include "PlfmDef.h"
  73. #endif
  74.  
  75. #ifndef SOM_ODSession_xh
  76. #include <ODSessn.xh>
  77. #endif
  78.  
  79. #ifndef _ODUTILS_
  80. #include "ODUtils.h"
  81. #endif
  82.  
  83. #ifndef SOM_ODWindowState_xh
  84. #include <WinStat.xh>
  85. #endif
  86.  
  87. #ifndef _ORDCOLL_
  88. #include "OrdColl.h"
  89. #endif
  90.  
  91. #ifndef _CMDTABLE_
  92. #include "CmdTable.h"
  93. #endif
  94.  
  95. #ifndef _EXCEPT_
  96. #include "Except.h"
  97. #endif
  98.  
  99. #ifndef _ITEXT_
  100. #include "IText.h"
  101. #endif
  102.  
  103. #ifndef _ODDEBUG_
  104. #include "ODDebug.h"    // Adkins -- added
  105. #endif
  106.  
  107. #ifndef _TEMPOBJ_
  108. #include "TempObj.h"
  109. #endif
  110.  
  111. #ifndef _UTILERRS_
  112. #include "UtilErrs.h"
  113. #endif
  114.  
  115. #pragma segment ODMenuBar
  116.  
  117. #include "MenuBarB.cpp"    // Platform-independent methods, if any
  118.  
  119. //=====================================================================================
  120. // Constants
  121. //=====================================================================================
  122. #define kSyntheticMask    0x0F000000
  123. #define kMenuIDMask        0x00FFFF00
  124. #define kMenuIDShift    8
  125. #define kMenuItemMask    0x000000FF
  126.  
  127.  
  128. class ODPrivMenuInfo
  129. {
  130. public:
  131.     ODPrivMenuInfo(ODMenuID menuID, ODPlatformMenu menu,  
  132.                 ODPart* part, ODSShort position);
  133.     ~ODPrivMenuInfo();
  134.  
  135.     ODMenuID        fMenuID;
  136.     ODPlatformMenu  fMenu;
  137.     ODPart*            fPart;
  138.     ODSShort        fPosition;
  139. };
  140.  
  141. ODPrivMenuInfo::ODPrivMenuInfo( ODMenuID menuID, ODPlatformMenu menu, 
  142.                          ODPart* part, ODSShort position)
  143. {
  144.     fMenuID = menuID;
  145.     fMenu = menu;
  146.     fPart = part;
  147.     fPosition = position;
  148. }
  149.  
  150. ODPrivMenuInfo::~ODPrivMenuInfo()
  151. {
  152. }
  153.  
  154. //=====================================================================================
  155. // Class ODMenuBar
  156. //=====================================================================================
  157.  
  158.  
  159. SOM_Scope void  SOMLINK ODMenuBarInitMenuBar(ODMenuBar *somSelf, Environment *ev,
  160.         ODSession* session,
  161.         ODPlatformMenuBar menuBar)
  162. {
  163.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  164.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarInitMenuBar");
  165.  
  166.     SOM_TRY
  167.             
  168.         /* Moved from somInit. SOM itself sets fields to zero
  169.         _fSession = kODNULL;
  170.         _fSystemMenus = kODNULL;
  171.         _fCommandTable = kODNULL;
  172.         _fOtherMenus = kODNULL;
  173.         _fGeneration = 0;
  174.         */
  175.         
  176.         somSelf->InitRefCntObject(ev); 
  177.     
  178.         _fSession = session;
  179.         _fSystemMenus = menuBar;
  180.         
  181.     SOM_CATCH_ALL
  182.     SOM_ENDTRY
  183. }
  184.  
  185. SOM_Scope void  SOMLINK ODMenuBarAddSubMenu(ODMenuBar *somSelf, Environment *ev,
  186.         ODMenuID menuID,
  187.         ODPlatformMenu menu,
  188.         ODPart* part)
  189. {
  190.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  191.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarAddSubMenu");
  192.   
  193.       OrderedCollection* otherMenus = kODNULL; ODVolatile(otherMenus);
  194.     ODPrivMenuInfo* info = kODNULL; ODVolatile(info);
  195.       
  196.     WASSERT_IS_PART_WRAPPER( ev, part );
  197.  
  198.     SOM_TRY
  199.  
  200.         if (_fOtherMenus == kODNULL)
  201.         {
  202.             otherMenus = new OrderedCollection;
  203.             _fOtherMenus = otherMenus;
  204.         }
  205.         info = new ODPrivMenuInfo(menuID, menu,part, hierMenu);
  206.         _fOtherMenus->AddLast((ElementType) info);
  207.  
  208.         // if this is the current menu bar, we should also tell the Menu Manager
  209.         TempODMenuBar currentMenuBar = _fSession->GetWindowState(ev)->AcquireCurrentMenuBar(ev);
  210.         if (ODObjectsAreEqual(ev, currentMenuBar, somSelf))
  211.         {
  212.             ::InsertMenu(menu, hierMenu);
  213.             ::InvalMenuBar();
  214.         }
  215.  
  216.     SOM_CATCH_ALL
  217.     
  218.         ODDeleteObject(otherMenus);
  219.         ODDeleteObject(info);
  220.         
  221.     SOM_ENDTRY
  222.  
  223. }
  224.  
  225. SOM_Scope void  SOMLINK ODMenuBarRegisterCommand(ODMenuBar *somSelf, Environment *ev,
  226.         ODCommandID command,
  227.         ODMenuID menu,
  228.         ODMenuItemID menuItem)
  229. {
  230.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  231.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarRegisterCommand");
  232.     
  233.     CommandTable* table = kODNULL; ODVolatile(table);
  234.     
  235.     SOM_TRY
  236.  
  237.         if (_fCommandTable == kODNULL)
  238.         {
  239.             table = new CommandTable;
  240.             _fCommandTable = table;
  241.         }
  242.         _fCommandTable->RegisterCommand(command, menu, menuItem);
  243.     
  244.     SOM_CATCH_ALL
  245.     
  246.         ODDeleteObject(table);
  247.         
  248.     SOM_ENDTRY
  249. }
  250.  
  251. SOM_Scope void  SOMLINK ODMenuBarUnregisterCommand(ODMenuBar *somSelf, Environment *ev,
  252.         ODCommandID command)
  253. {
  254.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  255.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarUnregisterCommand");
  256.  
  257.     SOM_TRY
  258.     
  259.         if (_fCommandTable)
  260.             _fCommandTable->UnregisterCommand(command);
  261.         
  262.     SOM_CATCH_ALL
  263.     SOM_ENDTRY
  264. }
  265.  
  266. SOM_Scope void  SOMLINK ODMenuBarUnregisterAll(ODMenuBar *somSelf, Environment *ev)
  267. {
  268.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  269.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarUnregisterAll");
  270.  
  271.     SOM_TRY
  272.     
  273.         if (_fCommandTable)
  274.             _fCommandTable->UnregisterAll();
  275.  
  276.     SOM_CATCH_ALL
  277.     SOM_ENDTRY
  278. }
  279.  
  280.  
  281. SOM_Scope ODBoolean  SOMLINK ODMenuBarIsCommandRegistered(ODMenuBar *somSelf, Environment *ev,
  282.         ODCommandID command)
  283. {
  284.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  285.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarIsCommandRegistered");
  286.     
  287.     ODBoolean isRegistered = kODFalse;
  288.  
  289.     SOM_TRY
  290.     
  291.         if (_fCommandTable)
  292.             isRegistered = _fCommandTable->IsCommandRegistered(command);
  293.  
  294.     SOM_CATCH_ALL
  295.     SOM_ENDTRY
  296.     
  297.     return isRegistered;
  298. }
  299.  
  300. SOM_Scope ODBoolean  SOMLINK ODMenuBarIsCommandSynthetic(ODMenuBar *somSelf, Environment *ev,
  301.         ODCommandID command)
  302. {
  303. //    ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  304.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarIsCommandSynthetic");
  305.  
  306.     return (command&kSyntheticMask) == kSyntheticMask;
  307. }
  308.  
  309. SOM_Scope ODCommandID  SOMLINK ODMenuBarGetCommand(ODMenuBar *somSelf, Environment *ev,
  310.         ODMenuID menu,
  311.         ODMenuItemID menuItem)
  312. {
  313.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  314.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarGetCommand");
  315.  
  316.     ODCommandID command = kNoCommand;
  317.     
  318.     SOM_TRY
  319.     
  320.         if (_fCommandTable)
  321.             command = _fCommandTable->GetCommand(menu, menuItem);
  322.             
  323.         if (command == kNoCommand)
  324.             // No command in table, so synthesize one:
  325.             command = kSyntheticMask | ((long)menu<<kMenuIDShift) | (menuItem & kMenuItemMask);
  326.  
  327.     SOM_CATCH_ALL
  328.     SOM_ENDTRY
  329.         
  330.     return command;
  331. }
  332.  
  333. SOM_Scope ODBoolean SOMLINK ODMenuBarFindMenuAndItem(ODMenuBar *somSelf, Environment *ev,
  334.         ODCommandID command,
  335.         ODMenuID* menu,
  336.         ODMenuItemID* menuItem)
  337. {
  338.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  339.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarFindMenuAndItem");
  340.  
  341.     ODBoolean found = kODFalse;
  342.     *menu = 0;
  343.     *menuItem = 0;
  344.     
  345.     SOM_TRY
  346.     
  347.         if ( somSelf->IsCommandSynthetic( ev, command )) 
  348.         {    
  349.             *menu = (ODMenuID) (( command & kMenuIDMask ) >> kMenuIDShift );
  350.             *menuItem = (ODMenuItemID) ( command & kMenuItemMask );
  351.             found = kODTrue;
  352.         }
  353.         else if ( _fCommandTable )
  354.         {
  355.             found = _fCommandTable->GetMenuAndItem( command, *menu, *menuItem );
  356.         }
  357.  
  358.     SOM_CATCH_ALL
  359.     SOM_ENDTRY
  360.     
  361.     return found;
  362. }
  363.  
  364. SOM_Scope void  SOMLINK ODMenuBarGetMenuAndItem(ODMenuBar *somSelf, Environment *ev,
  365.         ODCommandID command,
  366.         ODMenuID* menu,
  367.         ODMenuItemID* menuItem)
  368. {
  369. //    ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  370.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarGetMenuAndItem");
  371.  
  372.     SOM_TRY
  373.  
  374.         if ( !somSelf->FindMenuAndItem( ev, command, menu, menuItem ))
  375.             THROW(kODErrInvalidCommandID);
  376.     
  377.     SOM_CATCH_ALL
  378.     SOM_ENDTRY
  379. }
  380.  
  381. SOM_Scope void  SOMLINK ODMenuBarEnableCommand(ODMenuBar *somSelf, Environment *ev,
  382.         ODCommandID cmdNumber,
  383.         ODBoolean enable)
  384. {
  385. //    ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  386.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarEnableCommand");
  387.  
  388.     SOM_TRY
  389.  
  390.         ODMenuID menuID;
  391.         ODMenuItemID item;
  392.         if ( somSelf->FindMenuAndItem( ev, cmdNumber, &menuID, &item ))
  393.         {
  394.             ODPlatformMenu macMenu = somSelf->GetMenu( ev, menuID ) ;
  395.             if (macMenu)
  396.             {
  397.                 if (enable)
  398.                     EnableItem(macMenu, item) ;
  399.                 else
  400.                     DisableItem(macMenu, item) ;
  401.             }
  402.         }
  403.     
  404.     SOM_CATCH_ALL
  405.     
  406.         SetErrorCode(kODNoError);
  407.         
  408.     SOM_ENDTRY
  409. }
  410.  
  411. SOM_Scope void  SOMLINK ODMenuBarCheckCommand(ODMenuBar *somSelf, Environment *ev,
  412.         ODCommandID cmdNumber,
  413.         ODBoolean check)
  414. {
  415. //    ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  416.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarCheckCommand");
  417.     
  418.     SOM_TRY
  419.  
  420.         ODMenuID menuID;
  421.         ODMenuItemID item;
  422.         if ( somSelf->FindMenuAndItem( ev, cmdNumber, &menuID, &item ))
  423.         {
  424.             ODPlatformMenu macMenu = somSelf->GetMenu( ev, menuID ) ;
  425.             if (macMenu)
  426.                 CheckItem(macMenu, item, check); 
  427.         }
  428.  
  429.     SOM_CATCH_ALL
  430.     
  431.         SetErrorCode(kODNoError);
  432.     
  433.     SOM_ENDTRY
  434.  
  435. }
  436.  
  437. SOM_Scope void  SOMLINK ODMenuBarEnableAndCheckCommand(ODMenuBar *somSelf, Environment *ev,
  438.         ODCommandID cmdNumber,
  439.         ODBoolean enable,
  440.         ODBoolean check)
  441. {
  442. //    ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  443.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarEnableAndCheckCommand");
  444.  
  445.     SOM_TRY
  446.  
  447.         ODMenuID menuID;
  448.         ODMenuItemID item;
  449.  
  450.         if ( somSelf->FindMenuAndItem( ev, cmdNumber, &menuID, &item ))
  451.         {
  452.             ODPlatformMenu macMenu = somSelf->GetMenu( ev, menuID );
  453.             if (macMenu)
  454.             {
  455.                 if ( enable )
  456.                     EnableItem(macMenu, item) ;
  457.                 else
  458.                     DisableItem(macMenu, item) ;
  459.                 CheckItem(macMenu, item, check); 
  460.             }
  461.         }
  462.  
  463.     SOM_CATCH_ALL
  464.  
  465.         SetErrorCode(kODNoError);
  466.  
  467.     SOM_ENDTRY
  468. }
  469.  
  470. SOM_Scope void  SOMLINK ODMenuBarSetItemString(ODMenuBar *somSelf, Environment *ev,
  471.         ODCommandID cmdNumber,
  472.         ODIText* itemString)
  473. {
  474.     const ODSShort    kUseSpecificScript = 0x1c;
  475.  
  476. //    ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  477.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarSetItemString");
  478.     
  479.     SOM_TRY
  480.  
  481.         ODMenuID menuID;
  482.         ODMenuItemID item;
  483.         if ( somSelf->FindMenuAndItem( ev, cmdNumber, &menuID, &item ))
  484.         {
  485.             ODPlatformMenu macMenu = somSelf->GetMenu( ev, menuID ) ;
  486.             if( macMenu != kODNULL ) 
  487.             {
  488.                 StringPtr s = GetPStringFromIText(itemString);
  489.                 SetMenuItemText(macMenu, item, s); 
  490.                 ODDisposePtr(s);
  491.             
  492.                 short scriptID = GetITextScriptCode(itemString);
  493.                 ODSLong    savedSMFontForceFlag = GetScriptManagerVariable(smFontForce);
  494.                 SetScriptManagerVariable(smFontForce, false);
  495.  
  496.                 // if the scriptID is smSystemScript (which in our use means whatever
  497.                 // the current app script is) then set it to the actual value.  Simply
  498.                 // checking that it's not that constant before continuing does the same
  499.                 // thing in this case.
  500.                 if ( (scriptID != smSystemScript)
  501.                         && (scriptID != FontToScript( GetAppFont() )) )
  502.                 {
  503.                     SetItemCmd(macMenu, item, kUseSpecificScript);
  504.                     SetItemIcon(macMenu, item, scriptID);
  505.                 }
  506.                 
  507.                 SetScriptManagerVariable(smFontForce, savedSMFontForceFlag);
  508.             }
  509.         }
  510.  
  511.     SOM_CATCH_ALL
  512.  
  513.         SetErrorCode(kODNoError);
  514.  
  515.     SOM_ENDTRY
  516. }
  517.  
  518. SOM_Scope void  SOMLINK ODMenuBarGetItemString(ODMenuBar *somSelf, Environment *ev,
  519.         ODCommandID cmdNumber,
  520.         ODIText* itemString)
  521. {
  522.     const ODSShort    kUseSpecificScript = 0x1c;
  523.  
  524. //    ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  525.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarGetItemString");
  526.     
  527.     SOM_TRY
  528.  
  529.         ODMenuID menuID;
  530.         ODMenuItemID item;
  531.         if ( somSelf->FindMenuAndItem( ev, cmdNumber, &menuID, &item ))
  532.         {
  533.             ODPlatformMenu macMenu = somSelf->GetMenu( ev, menuID ) ;
  534.             if (macMenu)
  535.             {
  536.                 if (itemString)    
  537.                 {
  538.                     itemString->format = kODTraditionalMacText;
  539.                     itemString->text._buffer = kODNULL;
  540.                 }
  541.                 
  542.                 Str255 s;
  543.                 GetMenuItemText(macMenu, item, s); 
  544.                 SetITextString(itemString, s);
  545.                 
  546.                 // Is this correct?
  547.                 short cmd;
  548.                 short scriptID = smSystemScript;
  549.                 ODSLong    savedSMFontForceFlag = GetScriptManagerVariable(smFontForce);
  550.                 SetScriptManagerVariable(smFontForce, false);
  551.                 GetItemCmd (macMenu, item, &cmd);
  552.                 if (cmd == kUseSpecificScript)
  553.                 {
  554.                     GetItemIcon (macMenu, item, &scriptID);
  555.                 }
  556.                 SetITextScriptCode(itemString, scriptID);
  557.                 SetITextLangCode(itemString, langEnglish);
  558.                 SetScriptManagerVariable(smFontForce, savedSMFontForceFlag);
  559.             }
  560.         }
  561.  
  562.     SOM_CATCH_ALL
  563.     SOM_ENDTRY
  564. }
  565.  
  566. SOM_Scope void  SOMLINK ODMenuBarSetCommandTable(ODMenuBar *somSelf, Environment *ev,
  567.         CommandTable* table)
  568. {
  569.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  570.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarSetCommandTable");
  571.  
  572.     _fCommandTable = table;
  573. }
  574.  
  575. SOM_Scope void  SOMLINK ODMenuBarDisableAll(ODMenuBar *somSelf, Environment *ev)
  576. {
  577.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  578.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarDisableAll");
  579.  
  580.     SOM_TRY
  581.     
  582.         if (_fOtherMenus)
  583.         {
  584.             ODPlatformMenu platformMenu = kODNULL;
  585.             OrderedCollectionIterator iter(_fOtherMenus);
  586.             for (ODPrivMenuInfo* menuInfo = (ODPrivMenuInfo*) iter.First();
  587.                 iter.IsNotComplete();
  588.                 menuInfo = (ODPrivMenuInfo*) iter.Next())
  589.             {
  590.                 platformMenu = menuInfo->fMenu;
  591.                 DisableItem(platformMenu,0);
  592.             }
  593.         }
  594.         
  595.     SOM_CATCH_ALL
  596.     SOM_ENDTRY
  597. }
  598.  
  599. SOM_Scope void  SOMLINK ODMenuBarEnableAll(ODMenuBar *somSelf, Environment *ev)
  600. {
  601.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  602.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarEnableAll");
  603.  
  604.     SOM_TRY
  605.     
  606.         if (_fOtherMenus)
  607.         {
  608.             ODPlatformMenu platformMenu = kODNULL;
  609.             OrderedCollectionIterator iter(_fOtherMenus);
  610.             for (ODPrivMenuInfo* menuInfo = (ODPrivMenuInfo*) iter.First();
  611.                 iter.IsNotComplete();
  612.                 menuInfo = (ODPrivMenuInfo*) iter.Next())
  613.             {
  614.                 platformMenu = menuInfo->fMenu;
  615.                 EnableItem(platformMenu,0);
  616.             }
  617.         }
  618.     SOM_CATCH_ALL
  619.     SOM_ENDTRY
  620. }
  621.  
  622. SOM_Scope void  SOMLINK ODMenuBarsomUninit(ODMenuBar *somSelf)
  623. {
  624.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  625.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarsomUninit");
  626.  
  627.     ODDeleteObject(_fCommandTable);
  628.  
  629.     if (_fOtherMenus)
  630.     {
  631.         TRY
  632.             OrderedCollectionIterator* iter = _fOtherMenus->CreateIterator();
  633.             for (ElementType t = iter->First(); iter->IsNotComplete(); t = iter->Next())
  634.             {
  635.                 ODDeleteObject(t);
  636.             }
  637.             ODDeleteObject(iter);
  638.             ODDeleteObject(_fOtherMenus);
  639.         CATCH_ALL
  640.             // Ignore any exceptions
  641.         ENDTRY
  642.     }
  643. }
  644.  
  645. SOM_Scope ODSize  SOMLINK ODMenuBarPurge(ODMenuBar *somSelf, Environment *ev,
  646.         ODSize size)
  647. {
  648. //    ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  649.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarPurge");
  650.  
  651.     ODSize purgeSize = 0;
  652.     
  653.     SOM_TRY
  654.     
  655.         purgeSize = parent_Purge(somSelf, ev, size);
  656.         
  657.     SOM_CATCH_ALL
  658.         WARN("Error %ld trying to purge in ODMenuBarPurge",ErrorCode());
  659.         SetErrorCode(kODNoError);        // dh - Eat the exception; Purge should not 
  660.                                         // propagate it because clients function
  661.                                         // fine whether memory was purged or not.
  662.     SOM_ENDTRY
  663.     
  664.     return purgeSize;
  665. }
  666.  
  667. SOM_Scope void  SOMLINK ODMenuBarRelease(ODMenuBar *somSelf, Environment *ev)
  668. {
  669. //    ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  670.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarRelease");
  671.     
  672.     SOM_TRY
  673.  
  674.         parent_Release(somSelf,ev);
  675.         if (somSelf->GetRefCount(ev) == 0) 
  676.             somSelf->somFree(); 
  677.         
  678.     SOM_CATCH_ALL
  679.     SOM_ENDTRY    
  680. }
  681.  
  682. SOM_Scope void  SOMLINK ODMenuBarDisplay(ODMenuBar *somSelf, Environment *ev)
  683. {
  684.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  685.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarDisplay");
  686.  
  687.     SOM_TRY
  688.  
  689.         if (_fSystemMenus) 
  690.         {
  691.             ClearMenuBar();
  692.             SetMenuBar(_fSystemMenus);
  693.         }
  694.         if (_fOtherMenus)
  695.         {
  696.             OrderedCollectionIterator iter(_fOtherMenus);
  697.             for (ODPrivMenuInfo* menu = (ODPrivMenuInfo*) iter.First();
  698.                 iter.IsNotComplete();
  699.                 menu = (ODPrivMenuInfo*) iter.Next())
  700.             {
  701.                 InsertMenu(menu->fMenu,menu->fPosition);
  702.             }
  703.         }
  704.         InvalMenuBar();
  705.         
  706.         _fSession->GetWindowState(ev)->SetCurrentMenuBar(ev,somSelf);
  707.         
  708.     SOM_CATCH_ALL
  709.     SOM_ENDTRY    
  710. }
  711.  
  712. SOM_Scope void  SOMLINK ODMenuBarAddMenuLast(ODMenuBar *somSelf, Environment *ev,
  713.         ODMenuID menuID,
  714.         ODPlatformMenu menu,
  715.         ODPart* part)
  716. {
  717.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  718.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarAddMenuLast");
  719.  
  720.       OrderedCollection* otherMenus = kODNULL; ODVolatile(otherMenus);
  721.     ODPrivMenuInfo* info = kODNULL; ODVolatile(info);
  722.     
  723.     WASSERT_IS_PART_WRAPPER( ev, part );
  724.  
  725.     SOM_TRY
  726.     
  727.         if (_fOtherMenus == kODNULL)
  728.         {
  729.             otherMenus = new OrderedCollection;
  730.             _fOtherMenus = otherMenus;
  731.         }
  732.         info = new ODPrivMenuInfo(menuID, menu,part, 0);
  733.         _fOtherMenus->AddLast((ElementType) info);
  734.  
  735.         // if this is the current menu bar, we should also tell the Menu Manager
  736.         TempODMenuBar currentMenuBar = _fSession->GetWindowState(ev)->AcquireCurrentMenuBar(ev);
  737.         if (ODObjectsAreEqual(ev, currentMenuBar, somSelf))
  738.         {
  739.             ::InsertMenu(menu, 0);
  740.             ::InvalMenuBar();
  741.         }
  742.  
  743.     SOM_CATCH_ALL
  744.     
  745.         ODDeleteObject(otherMenus);
  746.         ODDeleteObject(info);
  747.         
  748.     SOM_ENDTRY    
  749. }
  750.  
  751. SOM_Scope void  SOMLINK ODMenuBarAddMenuBefore(ODMenuBar *somSelf, Environment *ev,
  752.         ODMenuID menuID,
  753.         ODPlatformMenu menu,
  754.         ODPart* part,
  755.         ODMenuID beforeID)
  756. {
  757.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  758.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarAddMenuBefore");
  759.  
  760.       OrderedCollection* otherMenus = kODNULL; ODVolatile(otherMenus);
  761.     ODPrivMenuInfo* info = kODNULL; ODVolatile(info);
  762.  
  763.     WASSERT_IS_PART_WRAPPER( ev, part );
  764.  
  765.     SOM_TRY
  766.     
  767.         if (_fOtherMenus == kODNULL)
  768.         {
  769.             otherMenus = new OrderedCollection;
  770.             _fOtherMenus = otherMenus;
  771.         }
  772.         info = new ODPrivMenuInfo(menuID, menu,part, beforeID);
  773.         _fOtherMenus->AddLast((ElementType) info);
  774.  
  775.         // if this is the current menu bar, we should also tell the Menu Manager
  776.         TempODMenuBar currentMenuBar = _fSession->GetWindowState(ev)->AcquireCurrentMenuBar(ev);
  777.         if (ODObjectsAreEqual(ev, currentMenuBar, somSelf))
  778.         {
  779.             ::InsertMenu(menu, beforeID);
  780.             ::InvalMenuBar();
  781.         }
  782.  
  783.     SOM_CATCH_ALL
  784.  
  785.         ODDeleteObject(otherMenus);
  786.         ODDeleteObject(info);
  787.  
  788.     SOM_ENDTRY    
  789. }
  790.  
  791. SOM_Scope void  SOMLINK ODMenuBarRemoveMenu(ODMenuBar *somSelf, Environment *ev,
  792.         ODMenuID menu)
  793. {
  794.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  795.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarRemoveMenu");
  796.  
  797.     ODPrivMenuInfo* foundMenu = kODNULL;
  798.     
  799.     SOM_TRY
  800.     
  801.         if (_fOtherMenus)
  802.         {
  803.             OrderedCollectionIterator iter(_fOtherMenus);
  804.             for (ODPrivMenuInfo* menuInfo = (ODPrivMenuInfo*) iter.First();
  805.                 iter.IsNotComplete();
  806.                 menuInfo = (ODPrivMenuInfo*) iter.Next())
  807.             {
  808.                 if (menuInfo->fMenuID == menu)
  809.                 {
  810.                     foundMenu = menuInfo;
  811.                     break;
  812.                 }
  813.             }
  814.             if (foundMenu)
  815.             {
  816.                 _fOtherMenus->Remove((ElementType) foundMenu);
  817.                 
  818.                 // if this is the current menu bar, we should also tell the Menu Manager
  819.                 TempODMenuBar currentMenuBar = _fSession->GetWindowState(ev)->AcquireCurrentMenuBar(ev);
  820.                 if (ODObjectsAreEqual(ev, currentMenuBar, somSelf))
  821.                 {
  822.                     ::DeleteMenu(menu);
  823.                     ::InvalMenuBar();
  824.                 }
  825.             }
  826.             ODDeleteObject(foundMenu);
  827.         }
  828.  
  829.     SOM_CATCH_ALL
  830.     SOM_ENDTRY    
  831. }
  832.  
  833. SOM_Scope ODPlatformMenu  SOMLINK ODMenuBarGetMenu(ODMenuBar *somSelf, Environment *ev,
  834.         ODMenuID menu)
  835. {
  836.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  837.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarGetMenu");
  838.  
  839.     ODPlatformMenu platformMenu = kODNULL;
  840.     
  841.     SOM_TRY
  842.     
  843.     if (_fOtherMenus)
  844.     {
  845.         OrderedCollectionIterator iter(_fOtherMenus);
  846.         for (ODPrivMenuInfo* menuInfo = (ODPrivMenuInfo*) iter.First();
  847.             iter.IsNotComplete();
  848.             menuInfo = (ODPrivMenuInfo*) iter.Next())
  849.         {
  850.             if (menuInfo->fMenuID == menu)
  851.             {
  852.                 platformMenu = menuInfo->fMenu;
  853.                 break;
  854.             }
  855.         }
  856.     }
  857.     // In case it's in the system menus:
  858.     if (platformMenu == kODNULL)
  859.         platformMenu = GetMenuHandle(menu);
  860.  
  861.     SOM_CATCH_ALL
  862.     SOM_ENDTRY    
  863.  
  864.     return platformMenu;
  865. }
  866.  
  867. SOM_Scope ODBoolean  SOMLINK ODMenuBarIsValid(ODMenuBar *somSelf, Environment *ev)
  868. {
  869.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  870.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarIsValid");
  871.     
  872.     ODBoolean isValid = kODFalse;
  873.     
  874.     SOM_TRY
  875.  
  876.         ODMenuBar* baseMenuBar = _fSession->GetWindowState(ev)->AcquireBaseMenuBar(ev); 
  877.         if (baseMenuBar)
  878.             isValid = _fGeneration == baseMenuBar->GetGeneration(ev);
  879.         baseMenuBar->Release(ev);
  880.         
  881.     SOM_CATCH_ALL
  882.     SOM_ENDTRY
  883.     
  884.     return isValid;
  885. }
  886.  
  887.  
  888. SOM_Scope void  SOMLINK ODMenuBarSetGeneration(ODMenuBar *somSelf, Environment *ev,
  889.         ODULong generation)
  890. {
  891.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  892.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarSetGeneration");
  893.  
  894.     _fGeneration = generation;
  895. }
  896.  
  897.  
  898. SOM_Scope ODULong  SOMLINK ODMenuBarGetGeneration(ODMenuBar *somSelf, Environment *ev)
  899. {
  900.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  901.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarGetGeneration");
  902.  
  903.     return _fGeneration;
  904. }
  905.  
  906. SOM_Scope ODMenuBar*  SOMLINK ODMenuBarCopy(ODMenuBar *somSelf, Environment *ev)
  907. {
  908.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  909.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarCopy");
  910.  
  911.     // Needs work, obviously!
  912.  
  913.     ODMenuBar* copy = kODNULL; ODVolatile(copy);
  914.     
  915.     SOM_TRY
  916.     
  917.         copy = new ODMenuBar();
  918.         THROW_IF_NULL(copy); // "new" does not THROW for SOM objects
  919.         copy->InitMenuBar(ev, _fSession,_fSystemMenus);
  920.     
  921.         if (_fOtherMenus)
  922.         {
  923.             OrderedCollectionIterator iter(_fOtherMenus);
  924.             for (ODPrivMenuInfo* menu = (ODPrivMenuInfo*) iter.First();
  925.                 iter.IsNotComplete();
  926.                 menu = (ODPrivMenuInfo*) iter.Next())
  927.             {
  928.                 if (menu->fPosition == 0)
  929.                     copy->AddMenuLast(ev, menu->fMenuID, menu->fMenu, menu->fPart);
  930.                 else if (menu->fPosition == hierMenu)
  931.                     copy->AddSubMenu(ev, menu->fMenuID, menu->fMenu, menu->fPart);
  932.                 else 
  933.                     copy->AddMenuBefore(ev, menu->fMenuID, menu->fMenu, 
  934.                                         menu->fPart, menu->fPosition);
  935.             }
  936.         }
  937.         
  938.         if (_fCommandTable) //!!! eeewh!!!
  939.         {
  940.             // copy->fCommandTable = _fCommandTable->Copy();
  941.             copy->SetCommandTable(ev, _fCommandTable->Copy() );    // <eeh> was somSelf->SetCommandTable
  942.         }
  943.         
  944.         copy->SetGeneration(ev, _fGeneration);
  945.  
  946.     SOM_CATCH_ALL
  947.         
  948.         ODDeleteObject(copy);
  949.         
  950.     SOM_ENDTRY
  951.             
  952.     return copy;
  953. }
  954.